package com.clp.protocol.iec104.client.pipeline.state.data;

import com.clp.protocol.iec104.apdu.asdu.IAsdu;
import com.clp.protocol.iec104.client.pipeline.MPipelineManager;
import com.clp.protocol.iec104.client.pipeline.state.AbstractMStateHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;

public abstract class AbstractMDataStateHandler extends AbstractMStateHandler {
    public AbstractMDataStateHandler(MPipelineManager manager) {
        super(manager);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg == null) return;
        if (!(msg instanceof IAsdu)) {
            ctx.fireChannelRead(msg);
            return;
        }

        try {
            IAsdu iAsdu = updateStateByRecv(((IAsdu) msg));
            if (iAsdu == null) return;
            ctx.fireChannelRead(iAsdu);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 抛出异常会取消接收这个asdu
     * @param iAsdu
     * @return
     * @throws Exception
     */
    protected abstract IAsdu updateStateByRecv(IAsdu iAsdu) throws Exception;

    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        if (msg == null) return;
        if (!(msg instanceof IAsdu)) {
            ctx.write(msg, promise);
            return;
        }

        try {
            IAsdu iAsdu = updateStateBySend(((IAsdu) msg));
            if (iAsdu == null) {
                promise.setFailure(new IllegalStateException("发送的asdu更新状态时被过滤"));
                return;
            }
            ctx.write(msg, promise);
        } catch (Exception e) {
            e.printStackTrace();
            promise.setFailure(e);
        }
    }

    /**
     * 抛出异常会取消发送这个asdu
     * @param iAsdu
     * @return
     * @throws Exception
     */
    protected abstract IAsdu updateStateBySend(IAsdu iAsdu) throws Exception;
}
